package com.quectel.taskserver.job.patrol;

import cn.hutool.core.date.DateUtil;
import com.quectel.business.common.dept.DeptPersonMsgBusiness;
import com.quectel.constant.PushConstants;
import com.quectel.constant.core.dept.DeptPersonMsgConstants;
import com.quectel.constant.core.securitypatrol.SecurityPatrolTaskConstants;
import com.quectel.constant.core.videopatrol.VideoPatrolTaskConstants;
import com.quectel.core.module.dept.dto.DeptPersonDto;
import com.quectel.core.module.dept.service.DeptPersonService;
import com.quectel.core.module.patrol.dto.VideoPatrolPlanDto;
import com.quectel.core.module.patrol.dto.VideoPatrolTaskDto;
import com.quectel.core.module.patrol.service.VideoPatrolPlanService;
import com.quectel.core.module.patrol.service.VideoPatrolTaskService;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.JacksonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static cn.hutool.core.text.CharSequenceUtil.splitTrim;

/**
 * 根据视频巡更计划生成任务
 *
 * @author caolu
 * @email louis.cao@quectel.com
 */
@Component
public class VideoPatrolGenerateTask implements SimpleJob {
    private static final Logger LOGGER = LoggerFactory.getLogger(VideoPatrolGenerateTask.class);
    @DubboReference
    private VideoPatrolPlanService videoPatrolPlanService;
    @DubboReference
    private VideoPatrolTaskService videoPatrolTaskService;
    @DubboReference
    private DeptPersonService deptPersonService;

    @Autowired
    private DeptPersonMsgBusiness deptPersonMsgBusiness;

    @Override
    public void execute(ShardingContext shardingContext) {
        videoPatrolGenerateTask();
    }

    public void videoPatrolGenerateTask() {
        LOGGER.info("视频巡更任务开始执行... 时间 {} 下面各个机器开始抢占执行",
                DateUtils.getCurrentDateStr(DateUtils.FormatType.COMMON));
        Date nextDate = new Date(System.currentTimeMillis() + 24L * 60 * 60 * 1000);
        String nextDay = new SimpleDateFormat("yyyy-MM-dd")
                .format(nextDate);
        Date now = new Date();
        //抢占执行生成任务
        LOGGER.info("本次本台机器可以执行生成任务,要生成{}的巡更任务", nextDay);

        List<VideoPatrolPlanDto> result = new ArrayList<>();
        int pageNo = 1;
        while (true) {
            Map<String, Object> queryMap = new HashMap<>();
            queryMap.put("startTime", nextDay);
            queryMap.put("endTime", nextDay);
            queryMap.put("offset", (pageNo - 1) * 2000);
            queryMap.put("limit", 2000);
            List<VideoPatrolPlanDto> list = videoPatrolPlanService.queryList(queryMap);
            if (list.size() <= 0) {
                break;
            }
            result.addAll(list);
            pageNo++;
        }
        LOGGER.info("要执行巡更计划的条数{}", result.size());
        for (VideoPatrolPlanDto videoPatrolPlanDto : result) {
            if (StringUtils.isNotBlank(videoPatrolPlanDto.getWeekPlan())) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(nextDate);
                int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
                if (dayOfWeek - 1 == 0) {
                    dayOfWeek = 7;
                } else {
                    dayOfWeek--;
                }
                List<String> weekPlan = JacksonUtils.parseArray(videoPatrolPlanDto.getWeekPlan(), String.class);
                if (!weekPlan.contains(dayOfWeek + "")) {
                    //日期不满足
                    continue;
                }

                if (StringUtils.isNotBlank(videoPatrolPlanDto.getDayPeriodArr())) {
                    List<String> parseArray = JacksonUtils.parseArray(videoPatrolPlanDto.getDayPeriodArr(), String.class);
                    for (String period : parseArray) {
                        try {
                            //没个时间段生成
                            VideoPatrolTaskDto videoPatrolTaskDto = new VideoPatrolTaskDto();
                            videoPatrolTaskDto.setTenantId(videoPatrolPlanDto.getTenantId());
                            videoPatrolTaskDto.setVillageId(videoPatrolPlanDto.getVillageId());
                            videoPatrolTaskDto.setPlanId(videoPatrolPlanDto.getId());
                            videoPatrolTaskDto.setPlanJson(JacksonUtils.toJsonString(videoPatrolPlanDto));
                            videoPatrolTaskDto.setName(
                                    String.format("%s-%s-%s", nextDay, videoPatrolPlanDto.getName(), period)
                            );
                            videoPatrolTaskDto.setExecUserId(videoPatrolPlanDto.getExecUserId());
                            videoPatrolTaskDto.setExecUsername(videoPatrolPlanDto.getExecUsername());
                            videoPatrolTaskDto.setDate(nextDay);
                            videoPatrolTaskDto.setPeriod(period);
                            List<String> datePeriod = splitTrim(period, "-");
                            List<String> collect = datePeriod.stream()
                                    .map(v -> nextDay + " " + v + ":00")
                                    .collect(Collectors.toList());

                            videoPatrolTaskDto.setExecStartTime(DateUtil.parse(collect.get(0), DateUtils.FormatType.COMMON.getType()));
                            videoPatrolTaskDto.setExecEndTime(DateUtil.parse(collect.get(1), DateUtils.FormatType.COMMON.getType()));

                            if (videoPatrolPlanDto.getVideoPatrolRouteDto() != null) {
                                videoPatrolTaskDto.setRouteArr(
                                        videoPatrolPlanDto.getVideoPatrolRouteDto().getRouteArr());
                            }
                            videoPatrolTaskDto.setVideoPlayDuration(videoPatrolPlanDto.getVideoPlayDuration());
                            videoPatrolTaskDto.setExecStatus((byte) 0);
                            videoPatrolTaskDto.setCreateTime(now);
                            Long taskId = videoPatrolTaskService.save(videoPatrolTaskDto);


                            // 发消息通知第二天执行的巡更任务
                            DeptPersonDto deptPersonDto = deptPersonService.selectById(videoPatrolTaskDto.getExecUserId());
                            DeptPersonMsgConstants.SourceType securityPatrolMsg = DeptPersonMsgConstants.SourceType.VIDEO_PATROL_MSG;

                            if (null != deptPersonDto) {
                                deptPersonMsgBusiness.pushMsg(
                                        new ArrayList<>(Arrays.asList(deptPersonDto)),
                                        securityPatrolMsg,
                                        taskId,
                                        null,
                                        String.format(VideoPatrolTaskConstants.VIDEO_PATROL_PUSH_MSG_TEMPLATE,
                                                videoPatrolTaskDto.getName(), videoPatrolTaskDto.getDate(), videoPatrolTaskDto.getPeriod()),
                                        true,
                                        new PushConstants.PushType[]{PushConstants.PushType.WECHAT_OFFICIAL});
                                LOGGER.info("向{}推动次日视频巡检任务成功", deptPersonDto.getName());
                                videoPatrolTaskDto.setId(taskId);
                                videoPatrolTaskDto.setIsPush(SecurityPatrolTaskConstants.IsPushedEnum.IS_PUSHED.getIsPushed());
                                videoPatrolTaskService.updateById(videoPatrolTaskDto);
                            } else {
                                LOGGER.info("向{}推动次日视频巡检任务失败", deptPersonDto.getName());
                                videoPatrolTaskDto.setId(taskId);
                                videoPatrolTaskDto.setIsPush(SecurityPatrolTaskConstants.IsPushedEnum.IS_NOT_PUSHED.getIsPushed());
                                videoPatrolTaskService.updateById(videoPatrolTaskDto);
                            }
                        } catch (Exception e) {
                            continue;
                        }

                    }
                }
            }

            LOGGER.info("{}视频巡更任务已生成完毕", nextDay);
        }
    }


}























